import { ExtendCalendarProps, ExtendCalendarPropsType } from '../extend-calendar.props';
import { SetupContext, Ref, ref, nextTick,onMounted, onUnmounted, computed,watch } from 'vue';
import useDate from '../composition/use-date.methods'
export default function (
    props: ExtendCalendarPropsType,
    context: SetupContext,
) {
    let calendarDayRef = ref();
    let calendarDayLayoutRef = ref();
    let selected = ref();
    let visible = ref(props.defaultVisible);
    let date = ref(new Date());
    let selftDate = ref(date.value);
    const { computedDate } = useDate(props, context);
    let calendarDates = ref(computedDate(date.value, props.data, props.beginWeek, selected));
    let boxHeight = ref(props.latticeHeight * calendarDates.value.length);
    let isRowItemDown = false;
    let rowItemMoveCount = 0;
    // 通过 判断 每个 日期的down和move滑动如果滑动 数值超过10则表示滑动 不是点击
    let isLayoutMouseEvent = false;
    let calendarMouseInfo = ref({
        startY: 0,
        endY: 0,
        moveY: 0
    })

    const calendarMove = (event: MouseEvent) => {
        if(!props.isDrag) return;
        calendarDayLayoutRef.value.style.transition = 'none';
        calendarDayRef.value?.classList?.remove('f-extend-calendar-days_transition');
        let moveY = event.pageY - calendarMouseInfo.value.startY;
        let dif = event.pageY - calendarMouseInfo.value.startY;
        if (visible.value) {
            if (dif < 0) {
                moveY = 0;
            }
            moveY = -(boxHeight.value - props.latticeHeight - moveY);
            let daybox_height = (boxHeight.value + moveY);
            if (daybox_height > boxHeight.value) {
                daybox_height = boxHeight.value;
                visible.value = false;
            }
            [...calendarDayRef.value.querySelectorAll('.f-extend-calendar-days-row')].map(d => {
                d.classList.add('noopacity-calendarToggle-day-row');
            })
            calendarDayRef.value.classList.add('f-extend-calendar-days-boxheight')
        } else {
            if (moveY < -(boxHeight.value - props.latticeHeight)) {
                moveY = -(boxHeight.value - props.latticeHeight);
                visible.value = true;
            }
            if (dif > 0) {
                moveY = 0;
            }
        }
        calendarMouseInfo.value.moveY = moveY;
        if (calendarMouseInfo.value.moveY < 0) {
            calendarDayLayoutRef.value.style.top = calendarMouseInfo.value.moveY + 'px';
        }
    }

    const initTransition = () => {
        if(!calendarDayLayoutRef.value && !calendarDayRef.value) return;
        // 删除由mouse事件修改的style
        calendarDayLayoutRef.value.removeAttribute('style');
        // 过渡初始到 css设置的
        calendarDayRef.value.classList.add('f-extend-calendar-days_transition')
        // 格子点击事件 true（收起）时候设置的切换上月下月过渡效果取消
        // 这里每次展开恢复
        calendarDayRef.value.classList.remove('clearDayopacity-transition');
    }
    const noTransition = () => {
        if(!calendarDayLayoutRef.value && !calendarDayRef.value) return;
        // 如果为收起状态切换日期;去掉过渡
        calendarDayRef.value.classList.remove('f-extend-calendar-days_transition');
        calendarDayLayoutRef.value.style.transition = 'none';
        calendarDayRef.value.classList.add('clearDayopacity-transition');
    }

    const calendarUp = () => {
        let difference = calendarMouseInfo.value.startY - calendarMouseInfo.value.endY;
        if (difference !== 0 && calendarMouseInfo.value.startY !== 0) {
            if (difference > props.latticeHeight) {
                visible.value = true;
            } else {
                visible.value = false;
            }
            initTransition();
            [...calendarDayRef.value.querySelectorAll('.f-extend-calendar-days-row')].map(d => {
                d.classList.remove('noopacity-calendarToggle-day-row');
            })
        }
    }
    const rowItemDown = (event: MouseEvent) => {
        if(!props.isDrag) return;
        if (event.button === 0) {
            isRowItemDown = true;
            isLayoutMouseEvent = false;
            rowItemMoveCount = 0;
            calendarMouseInfo.value.startY = event.pageY;
        }
    }
    const rowItemMove = (event: MouseEvent) => {
        if (isRowItemDown) {
            rowItemMoveCount++;
            if (rowItemMoveCount > 5 && !isLayoutMouseEvent) {
                isLayoutMouseEvent = true;
            }
            if (rowItemMoveCount > 5) {
                calendarMove(event);
            }
        }
        return event.preventDefault();
    }
    const initDownParans = () => {
        calendarMouseInfo.value.startY = 0;
        calendarMouseInfo.value.endY = 0;
        calendarMouseInfo.value.moveY = 0;
        isRowItemDown = false;
        rowItemMoveCount = 0;
    }
    const isDate = (item: any, od: any) => {
        let d = new Date(od);
        if (item.day === d.getDate() && item.month === d.getMonth() && item.year === d.getFullYear()) {
            return true;
        } else {
            return false;
        }
    }

    // 用来控制 点击 格子 的日期是否重复， true 重复 false不重复
    // 重复是 相当于取消选中，点击第一次选中，第二次取消
    let isClickDate = ref(false);
    const rowItemUp = (event: MouseEvent, item: any, rindex: number) => {
        if (event.button !== 0) return;
        if (!isLayoutMouseEvent) {
            if (visible.value) {
                noTransition();
            }
            selected.value = rindex + 1;
            let date_ = new Date(item.dateStr);
            calendarDates.value = computedDate(date_, props.data, props.beginWeek, selected);
            boxHeight.value = props.latticeHeight * calendarDates.value.length;
            if (isDate(item, date.value) && !isClickDate.value) {
                isClickDate.value = true;
            } else {
                isClickDate.value = false;
            }
            date.value = date_;
            context.emit('clickItem', item, rindex);
        } else {
            calendarMouseInfo.value.endY = event.pageY;
            calendarUp();
        }
    }
    /** 拖拽中，超出日历范围的抬起同样控制展开收起*/ 
    const docMouseUp = (event:MouseEvent) =>{
        calendarMouseInfo.value.endY = event.pageY;
        calendarUp();
        initDownParans();
    }
    /** 拖拽中，如果切换tab 让日历恢复至初始状态*/ 
    const winBlurFn = () => {
        if(rowItemMoveCount>5){
            visible.value = false;
            calendarDayLayoutRef.value.style = null;
            initDownParans();
            switchCalendarDates(date.value);
        }
    }
    onUnmounted(() => {
        document.removeEventListener('mouseup',docMouseUp);
        window.removeEventListener('blur',winBlurFn);
    })
    onMounted(()=>{
        document.addEventListener('mouseup',docMouseUp);
        window.addEventListener('blur', winBlurFn);
        winBlurFn();
    })
    watch(visible,()=>{
        nextTick(() => {
            if (!visible.value) {
                initTransition();
            }
        })
    })
    const switchCalendarDates = (d: any) => {
        if (visible.value) {
            noTransition();
        }
        let date_ = new Date(d);
        calendarDates.value = computedDate(date_, props.data, props.beginWeek, selected);
        boxHeight.value = props.latticeHeight * calendarDates.value.length;
    }

    const renderDayTask = (item: any) => {
        return <div class='f-extend-calendar-days-row-day-task'>
            {
                item?.task?.task && item.task.task.map((v: any) => {
                    let classStatusName = 'f-extend-calendar-days-row-day-task-item f-extend-calendar-days-status-level' + (v?.level || 1)
                    return <span class={classStatusName}></span>
                })
            }
        </div>
    }
    const renderRowItems = (items: any[], rindex: number) => {
        return items.map((item: any) => {
            let statusClassName = 'f-extend-calendar-days-row-day';
            if (item.status === -1) {
                statusClassName += ' f-extend-calendar-days-row-day-prevgrey'
            }
            if (item.status === 0) {
                statusClassName += ' f-extend-calendar-days-row-day-nextgrey'
            }
            if (isDate(item, selftDate.value)) {
                statusClassName += ' f-extend-calendar-days-row-day-selected'
            }
            if (isDate(item, date.value) && !isClickDate.value) {
                statusClassName += ' f-extend-calendar-days-row-day-click'
            }
            return <div class={statusClassName}
                onMousedown={rowItemDown}
                onMousemove={rowItemMove}
                onMouseup={(event: MouseEvent) => rowItemUp(event, item, rindex)}>
                <div class='f-extend-calendar-days-row-day-cell'>
                    <div class='f-extend-calendar-days-row-day-label'>
                        {item.day}
                    </div>
                    {renderDayTask(item)}
                </div>
            </div>
        })
    }
    const renderRow = () => {
        return calendarDates.value.map((row: any[], rindex: number) => {
            let className = 'f-extend-calendar-days-row';
            if ((rindex + 1) === selected.value) {
                className += ' f-extend-calendar-days-selected';
            }
            return (<div class={className}>
                {renderRowItems(row, rindex)}
            </div>)
        })
    }

    const calendarDayClassName = () => {
        let className = 'f-extend-calendar-days f-extend-calendar-days_transition';
        if (visible.value) {
            className += ' f-extend-calendar-days-retract'
        }
        return className;
    }
    const calendarDayStyle = () => {
        return `
        --row-len:${calendarDates.value.length};
        --lattice-height: ${props.latticeHeight}px;
        --box-height:${boxHeight.value + calendarMouseInfo.value.moveY}px;
        --box-height-retract: ${-(calendarDates.value.length - 1) * props.latticeHeight}px;
        `
    }

    const dateTask = computed(() => {
        let fills = calendarDates.value.flat(1);
        let find = fills.find((item: any) => {
            if (isDate(item, date.value) && !isClickDate.value) {
                return item;
            }
        });
        return find;
    })

    const renderDay = () => {
        return (
            <>
                <div
                    ref={calendarDayRef}
                    class={calendarDayClassName()}
                    style={calendarDayStyle()}>
                    <div ref={calendarDayLayoutRef} class='f-extend-calendar-days-layout'>
                        {renderRow()}
                    </div>
                </div>
            </>
        )
    }
    return {
        renderDay, calendarDates, date, visible,
        switchCalendarDates,
        dateTask,
        selftDate,
    }
}